package com.wwj.app.v1;

import com.github.pagehelper.Page;
import com.wwj.core.common.Constants;
import com.wwj.core.server.entity.ServerConfig;
import com.wwj.core.server.service.IServerConfigService;
import com.wwj.core.wawa.entity.*;
import com.wwj.core.wawa.service.*;
import com.wwj.framework.controller.BaseController;
import com.wwj.framework.utils.ReturnData;
import net.sf.json.JSONObject;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;

/**
 * Created by Administrator on 2017/11/3.
 */
@Controller
@RequestMapping("/v1/player")
public class PlayerController extends BaseController {

    @Resource
    private IPlayerService playerService;

    @Resource
    private IPlayRecordService playRecordService;

    @Resource
    private IPlayerItemService playerItemService;

    @Resource
    private IPlayerItemChangeRecordService playerItemChangeRecordService;

    @Resource
    private IRoomService roomService;

    @Resource
    private IWaWaTypeService waWaTypeService;

    @Resource
    private IRoomPlayerService roomPlayerService;

    @Resource
    private IPlayerAddressService playerAddressService;

    @Resource
    private IServerConfigService serverConfigService;

    @Resource
    private JedisPool jedisPool;

    @RequestMapping("/{playerId}")
    @ResponseBody
    public ReturnData playerInfo(@PathVariable int playerId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if (player == null) {
                returnData.failure("找不到玩家信息!");
                return returnData;
            }

            returnData.success(player);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/bindInviteCode")
    @ResponseBody
    public ReturnData bindInviteCode(@PathVariable int playerId, @RequestParam String inviteCode) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if (player == null) {
                returnData.failure("找不到玩家信息!");
                return returnData;
            }
            Player invitor = playerService.findByInviteCode(inviteCode);
            if(invitor == null) {
                returnData.failure("邀请码错误，找不到邀请玩家信息!");
                return returnData;
            }

            playerService.dealBindInvitor(player, invitor);
            returnData.success(player);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/coin")
    @ResponseBody
    public ReturnData coinNum(@PathVariable int playerId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if (player == null) {
                returnData.failure("找不到玩家信息!");
                return returnData;
            }

            PlayerItem playerItem = playerItemService.findByPlayerId(playerId);
            returnData.success(playerItem);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/coupons")
    @ResponseBody
    public ReturnData listCoupons(@PathVariable int playerId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if (player == null) {
                returnData.failure("找不到玩家信息!");
                return returnData;
            }

            returnData.success(player);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/playRecords")
    @ResponseBody
    public ReturnData listPlayRecord(@PathVariable int playerId, @RequestParam int playResult, @RequestParam int isDeliver, @RequestParam(required = false) Integer pageNo, @RequestParam(required = false) Integer pageSize) {
        ReturnData returnData = new ReturnData();
        try {
            if(pageNo == null || pageNo == 0) {
                pageNo = 1;
            }
            if(pageSize == null || pageSize ==0) {
                pageSize = 10;
            }
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("playerId", playerId);
            if(playResult != 0) {
                params.put("playResult", playResult);
            }
            if(isDeliver != -1) {
                params.put("isDeliver", isDeliver);
            }
            int offset = (pageNo - 1) * pageSize;
            int limit = pageSize;
            Page<PlayRecord> playRecords = playRecordService.findByPage(params, offset, limit);
            returnData.success(playRecords);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/applyDeliver")
    @ResponseBody
    public ReturnData applyDeliver(@PathVariable int playerId, @RequestParam String playRecordIds, @RequestParam int playerAddressId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if (player == null) {
                returnData.failure("找不到玩家信息!");
                return returnData;
            }

            if(playRecordIds == null || playRecordIds.isEmpty()) {
                returnData.failure("请选择要发货的娃娃!");
                return returnData;
            }

            PlayerAddress playerAddress = playerAddressService.findById(playerAddressId);
            if(playerAddress == null) {
                returnData.failure("找不到收货地址信息!");
                return returnData;
            }

            List<Integer> playRecordIdList = new ArrayList<>();
            String[] ids = playRecordIds.split(",");
            for(String id : ids) {
                if(id != null && !id.isEmpty()) {
                    playRecordIdList.add(Integer.valueOf(id));
                }
            }

            boolean hasDeliveredWawa = false;
            for(Integer playRecordId : playRecordIdList) {
                PlayRecord playRecord = playRecordService.findById(playRecordId);
                if(playRecord != null && playRecord.getIsDeliver() != 0) {
                    hasDeliveredWawa = true;
                    break;
                }
            }
            if(hasDeliveredWawa) {
                returnData.failure("选中的娃娃有部分已申请发货，请重新选择!");
                return returnData;
            }

            playerService.dealApplyDeliver(player, playerAddress, playRecordIdList);
            returnData.success();
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/coinChanges")
    @ResponseBody
    public ReturnData listCoinChangeRecords(@PathVariable int playerId, @RequestParam(required = false) Integer pageNo, @RequestParam(required = false) Integer pageSize) {
        ReturnData returnData = new ReturnData();
        try {
            if(pageNo == null || pageNo == 0) {
                pageNo = 1;
            }
            if(pageSize == null || pageSize ==0) {
                pageSize = 10;
            }
            int offset = (pageNo - 1) * pageSize;
            int limit = pageSize;
            Page<PlayerItemChangeRecord> changeRecords = playerItemChangeRecordService.findByPlayerIdInPage(playerId, offset, limit);
            returnData.success(changeRecords);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/enterRoom")
    @ResponseBody
    public ReturnData enterRoom(@PathVariable Integer playerId, @RequestParam Integer roomId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            room = playerService.dealEnterRoom(player, room);
            Jedis jedis = jedisPool.getResource();
            room.setPlayerCountInQueue(jedis.zcard(Constants.KEY_ROOM_QUEUE + roomId).intValue());
            player.setInRoomQueue(jedis.zrank(Constants.KEY_ROOM_QUEUE + roomId, player.getId().toString()) == null ? 0 : 1);
            jedis.close();
            Map<String,Object> result = new HashMap<String,Object>();
            result.put("room", room);
            result.put("player", player);
            returnData.success(result);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/leaveRoom")
    @ResponseBody
    public ReturnData leaveRoom(@PathVariable Integer playerId, @RequestParam Integer roomId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            playerService.dealLeaveRoom(player, room);
            returnData.success();
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/play")
    @ResponseBody
    public ReturnData play(@PathVariable Integer playerId, @RequestParam Integer roomId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            List<RoomPlayer> roomPlayers = roomPlayerService.findByRoomIdAndPlayerId(roomId, playerId);
            if(roomPlayers == null || roomPlayers.isEmpty()) {
                returnData.failure("玩家不在本房间中");
                return returnData;
            }

            if(room.getWaWaMachine().getStatus() != WaWaMachine.STATUS_IDLE) {
                returnData.failure("上机失败，房间不是处于空闲状态");
                return returnData;
            }

            if(room.getWaWaMachine().getIsOnline() == WaWaMachine.OFFLINE) {
                returnData.failure("上机失败，娃娃机处于离线状态");
                return returnData;
            }

            PlayerItem playerItem = playerItemService.findByPlayerId(playerId);
            if(playerItem == null) {
                returnData.failure("娃娃币不足，请充值", String.valueOf(Constants.WAWA_COIN_NOT_ENOUGH));
                return returnData;
            }

            int wawaTypeId = room.getWawaTypeId();
            WaWaType waWaType = waWaTypeService.findById(wawaTypeId);
            if(waWaType.getPayItemCount() > playerItem.getItemNum()) {
                returnData.failure("娃娃币不足，请充值", String.valueOf(Constants.WAWA_COIN_NOT_ENOUGH));
                return returnData;
            }

            Map<String, Object> result = playerService.dealPlay(player, room, waWaType);
            if(result != null) {
                returnData.success(result);
            } else {
                returnData.failure("您手速太慢了，已经被别人抢先了", String.valueOf(Constants.NO_CONTROL_POWER));
            }
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/continuePlay")
    @ResponseBody
    public ReturnData continuePlay(@PathVariable Integer playerId, @RequestParam Integer roomId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            List<RoomPlayer> roomPlayers = roomPlayerService.findByRoomIdAndPlayerId(roomId, playerId);
            if(roomPlayers == null || roomPlayers.isEmpty()) {
                returnData.failure("玩家不在本房间中");
                return returnData;
            }

            if(room.getWaWaMachine().getIsOnline() == WaWaMachine.OFFLINE) {
                returnData.failure("上机失败，娃娃机处于离线状态");
                return returnData;
            }

            if(room.getWaWaMachine().getCurrentPlayerId() == null
                    ||  !room.getWaWaMachine().getCurrentPlayerId().equals(playerId)) {
                returnData.failure("当前房主不是您，继续游戏失败");
                return returnData;
            }

            PlayerItem playerItem = playerItemService.findByPlayerId(playerId);
            if(playerItem == null) {
                returnData.failure("娃娃币不足，请充值", String.valueOf(Constants.WAWA_COIN_NOT_ENOUGH));
                return returnData;
            }

            int wawaTypeId = room.getWawaTypeId();
            WaWaType waWaType = waWaTypeService.findById(wawaTypeId);
            if(waWaType.getPayItemCount() > playerItem.getItemNum()) {
                returnData.failure("娃娃币不足，请充值", String.valueOf(Constants.WAWA_COIN_NOT_ENOUGH));
                return returnData;
            }

            Map<String, Object> result = playerService.dealContinuePlay(player, room, waWaType);
            returnData.success(result);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/queue")
    @ResponseBody
    public ReturnData queue(@PathVariable Integer playerId, @RequestParam Integer roomId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            List<RoomPlayer> roomPlayers = roomPlayerService.findByRoomIdAndPlayerId(roomId, playerId);
            if(roomPlayers == null || roomPlayers.isEmpty()) {
                returnData.failure("玩家不在本房间中");
                return returnData;
            }

            PlayerItem playerItem = playerItemService.findByPlayerId(playerId);
            if(playerItem == null) {
                returnData.failure("娃娃币不足，请充值", String.valueOf(Constants.WAWA_COIN_NOT_ENOUGH));
                return returnData;
            }

            int wawaTypeId = room.getWawaTypeId();
            WaWaType waWaType = waWaTypeService.findById(wawaTypeId);
            if(waWaType.getPayItemCount() > playerItem.getItemNum()) {
                returnData.failure("娃娃币不足，请充值", String.valueOf(Constants.WAWA_COIN_NOT_ENOUGH));
                return returnData;
            }
            playerService.dealQueue(player, room);
            returnData.success();
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/dequeue")
    @ResponseBody
    public ReturnData dequeue(@PathVariable Integer playerId, @RequestParam Integer roomId) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            List<RoomPlayer> roomPlayers = roomPlayerService.findByRoomIdAndPlayerId(roomId, playerId);
            if(roomPlayers == null || roomPlayers.isEmpty()) {
                returnData.failure("玩家不在本房间中");
                return returnData;
            }
            playerService.dealDequeue(player, room);
            returnData.success();
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/update")
    @ResponseBody
    public ReturnData updateInfo(@PathVariable Integer playerId, @Param("nickName") String nickName, MultipartHttpServletRequest request) {
        ReturnData returnData = new ReturnData();
        try {
            Player old = playerService.findById(playerId);
            if(old == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }
            Map<String,MultipartFile> multipartFileMap = request.getFileMap();
            Iterator<String> it = multipartFileMap.keySet().iterator();
            Map<String, Object> fileMap = null;
            while(it.hasNext()){
                MultipartFile multipartFile = multipartFileMap.get(it.next());
                if (multipartFile != null && !multipartFile.isEmpty()) {
                    File localFile = saveLocal(multipartFile.getInputStream(), multipartFile.getOriginalFilename());
                    fileMap = new HashMap<String, Object>();
                    fileMap.put("name", multipartFile.getOriginalFilename());
                    fileMap.put("size", multipartFile.getSize());
                    fileMap.put("contentType", multipartFile.getContentType());
                    fileMap.put("file", localFile);
                    break;
                }
            }
            playerService.updatePlayerInfo(playerId, nickName, fileMap);
            returnData.success(playerService.findById(playerId));
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    protected File saveLocal(InputStream inputStream, String fileName) throws Exception {
        File file = new File(getClass().getResource("").getPath(), System.currentTimeMillis() + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            fos.write(buffer, 0, length);
            fos.flush();
        }
        fos.close();
        inputStream.close();
        return file;
    }

    @RequestMapping("/{playerId}/online")
    @ResponseBody
    public ReturnData online(@PathVariable Integer playerId, @RequestParam String token) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            PlayRecord playRecord = playRecordService.findByToken(token);
            if (playRecord == null) {
                returnData.failure("找不到游戏记录");
                return returnData;
            }

            Room room = roomService.findById(playRecord.getRoomId());
            if(room == null) {
                returnData.failure("找不到房间记录");
                return returnData;
            }

            ServerConfig serverConfig = serverConfigService.findByType(ServerConfig.TYPE_GAME);
            Map<String, Object> retMap = new HashMap<>();
            retMap.put("serverConfig", serverConfig);
            retMap.put("waWaMachine", room.getWaWaMachine());
            retMap.put("playRecord", playRecord);

            returnData.success(retMap);
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }

    @RequestMapping("/{playerId}/sendBarrage")
    @ResponseBody
    public ReturnData sendBarrage(@PathVariable Integer playerId, @RequestParam Integer roomId, @RequestParam String barrage) {
        ReturnData returnData = new ReturnData();
        try {
            Player player = playerService.findById(playerId);
            if(player == null) {
                returnData.failure("找不到玩家信息");
                return returnData;
            }

            Room room = roomService.findById(roomId);
            if (room == null) {
                returnData.failure("找不到房间信息");
                return returnData;
            }

            Jedis jedis = jedisPool.getResource();
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("device_id", room.getWaWaMachine().getCode());
            jsonObj.put("user_id", player.getId());
            jsonObj.put("nickname", player.getNickname());
            jsonObj.put("header_icon", player.getHeaderIcon());
            jsonObj.put("barrage", barrage);
            jedis.lpush("barrage-queue", jsonObj.toString());
            returnData.success();
        } catch (Exception e) {
            logger.error("", e);
            returnData.failure("系统错误,请联系客服");
        }
        return returnData;
    }
}
